package com.bomberdroid.model;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;

import com.bomberdroid.protocols.DataSharing;
import com.bomberdroid.ui.GamePanel;

/**
 * Bombe est un Objet qui sera dans la grille de la Map
 * 
 */

public class Bombe extends Objet {
	/**
	 * Proprietaire de la bombe
	 */
	private Player owner;

	private static int imageAnim = 0;

	private static final int DEFAULTLIFETIME = 2000;

	private static java.util.Random ran = new java.util.Random();

	private static ArrayList<Bombe> bombes = new ArrayList<Bombe>();

	private int countdeath;

	/** int defini le ratio de bonus */
	private static int rate = 3;

	/**
	 * Constructeur
	 * 
	 * @param X
	 *            coordonnee x correspondant a sa place dans la grille
	 * @param Y
	 *            coordonneee y correspondant a sa place dans la grille
	 * @param J
	 *            Joueur a qui appartient la bombe que l'on va creer
	 * @param g
	 *            Reference sur la grille de la map dans laquelle est la Bombe
	 */

	public Bombe(int X, int Y, Player J, Objet[][] g) {
		// Appel du constructeur d'objet
		super(X, Y, g);
		owner = J;
		this.countdeath = Objet.getCount() + DEFAULTLIFETIME;
		bombes.add(this);
		if(GamePanel.server){
			DataSharing.message += "3;"+J.getIndice()+";"+X+";"+Y+"&";
		}
	}

	public Player getOwner() {
		return owner;
	}

	public boolean outOfBounds(int x, int y) {
		/* vrai si 0 < x <= 19 et 0 < y <= 15 */
		return !(x >= 0 && x < 19 && y >= 0 && y < 15);
	}

	public static void exploserLesBombes(int count) {
		Iterator<Bombe> b = bombes.iterator();
		while (b.hasNext()) {
			Bombe bo = b.next();
			if (bo.countdeath <= count) {
				b.remove();
				bo.explose();
			}
		}

	}

	public static void anim() {
		if (imageAnim <= 10)
			imageAnim++;
		else
			imageAnim = 0;
	}

	private void setCountDeath(int n) {
		this.countdeath = n;
	}

	/**
	 * Methode explose qui appele bombeExplose() du possesseur de la bombe Puis
	 * remplace la bombe par une flame et pose les flames autour de la bombe, en
	 * fonction de la puissance des flammes de son possesseur
	 */
	public void explose() {

		if(GamePanel.server)
			DataSharing.message += "4;"+this.x+";"+this.y+"&";
		
		owner.bombeExplose();
		int puissance = owner.getFlames();

		/* explosion du centre */
		grille[y][x] = new Flamme(x, y, grille, Flamme.CENTRE);

		/* indicateur de stop d'explosion */
		boolean owned = false;

		/* explosion vers le haut */
		for (int i = 1; i <= puissance && !owned; i++) {
			if (!outOfBounds(x, y - i)) {
				if (grille[y - i][x] instanceof Indestructible)
					owned = true;
				else if (grille[y - i][x] instanceof Flamme) {
					Flamme f = (Flamme) grille[y - i][x];
					if (f.getType() == Flamme.VERTICALE || f.getType() == Flamme.BAS || f.getType() == Flamme.HAUT) {
						grille[y - i][x] = new Flamme(x, y - i, grille, Flamme.VERTICALE);
						owned = true;
					} else
						grille[y - i][x] = new Flamme(x, y - i, grille, Flamme.CENTRE);

				} else if (grille[y - i][x] instanceof Bombe) {
					Bombe b = (Bombe) grille[y - i][x];
					b.setCountDeath(0);
					owned = true;
				} else {
					if (grille[y - i][x] instanceof Destructible) {
						owned = true;
						// bonus
						if (GamePanel.server) {
							if (Bombe.ran.nextInt(rate) == 0) {
								Random r = new Random();
								int rand = r.nextInt(3);
								/** Sending to client */
								DataSharing.message += "5;"+rand+";"+x+";"+(y-i)+"&";
								grille[y - i][x] = new Bonus(x, y - i, grille, rand);
							} else
								grille[y - i][x] = null;
						} else
							grille[y - i][x] = null;
					} else {
						if (i == puissance)
							grille[y - i][x] = new Flamme(x, y - i, grille, Flamme.HAUT);
						else
							grille[y - i][x] = new Flamme(x, y - i, grille, Flamme.VERTICALE);
					}
				}
			}
		}

		owned = false;

		/* explosion vers le bas */

		for (int i = 1; i <= puissance && !owned; i++) {
			if (!outOfBounds(x, y + i)) {
				if (grille[y + i][x] instanceof Indestructible)
					owned = true;
				else if (grille[y + i][x] instanceof Flamme) {
					Flamme f = (Flamme) grille[y + i][x];
					if (f.getType() == Flamme.VERTICALE || f.getType() == Flamme.BAS || f.getType() == Flamme.HAUT) {
						grille[y + i][x] = new Flamme(x, y + i, grille, Flamme.VERTICALE);
						owned = true;
					} else
						grille[y + i][x] = new Flamme(x, y + i, grille, Flamme.CENTRE);

				} else if (grille[y + i][x] instanceof Bombe) {
					Bombe b = (Bombe) grille[y + i][x];
					b.setCountDeath(0);
					owned = true;
				} else {
					if (grille[y + i][x] instanceof Destructible) {
						owned = true;
						// bonus
						if (GamePanel.server) {
							if (Bombe.ran.nextInt(rate) == 0) {
								Random r = new Random();
								int rand = r.nextInt(3);
								/** Sending to client */
								DataSharing.message += "5;"+rand+";"+x+";"+(y+i)+"&";
								grille[y + i][x] = new Bonus(x, y + i, grille, rand);
							} else
								grille[y + i][x] = null;
						} else
							grille[y + i][x] = null;
					} else {
						if (i == puissance)
							grille[y + i][x] = new Flamme(x, y + i, grille, Flamme.BAS);
						else
							grille[y + i][x] = new Flamme(x, y + i, grille, Flamme.VERTICALE);
					}
				}
			}
		}

		owned = false;

		/* explosion vers la gauche */

		for (int i = 1; i <= puissance && !owned; i++) {
			if (!outOfBounds(x - i, y)) {
				if (grille[y][x - i] instanceof Indestructible)
					owned = true;
				else if (grille[y][x - i] instanceof Flamme) {
					Flamme f = (Flamme) grille[y][x - i];
					if (f.getType() == Flamme.HORIZONTALE || f.getType() == Flamme.GAUCHE || f.getType() == Flamme.DROITE) {
						grille[y][x - i] = new Flamme(x - i, y, grille, Flamme.HORIZONTALE);
						owned = true;
					} else
						grille[y][x - i] = new Flamme(x - i, y, grille, Flamme.CENTRE);

				} else if (grille[y][x - i] instanceof Bombe) {
					Bombe b = (Bombe) grille[y][x - i];
					b.setCountDeath(0);
					owned = true;
				} else {
					if (grille[y][x - i] instanceof Destructible) {
						owned = true;
						// bonus
						if (GamePanel.server) {
							if (Bombe.ran.nextInt(rate) == 0) {
								Random r = new Random();
								int rand = r.nextInt(3);
								/** Sending to client */
								DataSharing.message += "5;"+rand+";"+(x-i)+";"+y+"&";
								grille[y][x - i] = new Bonus(x - i, y, grille, rand);
							} else
								grille[y][x - i] = null;
						} else
							grille[y][x - i] = null;
					} else {
						if (i == puissance)
							grille[y][x - i] = new Flamme(x - i, y, grille, Flamme.GAUCHE);
						else
							grille[y][x - i] = new Flamme(x - i, y, grille, Flamme.HORIZONTALE);
					}
				}
			}
		}

		owned = false;

		/* explosion vers la droite */

		for (int i = 1; i <= puissance && !owned; i++) {
			if (!outOfBounds(x + i, y)) {
				if (grille[y][x + i] instanceof Indestructible)
					owned = true;
				else if (grille[y][x + i] instanceof Flamme) {
					Flamme f = (Flamme) grille[y][x + i];
					if (f.getType() == Flamme.HORIZONTALE || f.getType() == Flamme.GAUCHE || f.getType() == Flamme.DROITE) {
						grille[y][x + i] = new Flamme(x + i, y, grille, Flamme.HORIZONTALE);
						owned = true;
					} else
						grille[y][x + i] = new Flamme(x + i, y, grille, Flamme.CENTRE);

				} else if (grille[y][x + i] instanceof Bombe) {
					Bombe b = (Bombe) grille[y][x + i];
					b.setCountDeath(0);
					owned = true;
				} else {
					if (grille[y][x + i] instanceof Destructible) {
						owned = true;
						// bonus
						if (GamePanel.server) {
							if (Bombe.ran.nextInt(rate) == 0) {
								Random r = new Random();
								int rand = r.nextInt(3);
								/** Sending to client */
								DataSharing.message += "5;"+rand+";"+(x+i)+";"+y+"&";
								grille[y][x + i] = new Bonus(x + i, y, grille, rand);
							} else
								grille[y][x + i] = null;
						} else
							grille[y][x + i] = null;
					} else {
						if (i == puissance)
							grille[y][x + i] = new Flamme(x + i, y, grille, Flamme.DROITE);
						else
							grille[y][x + i] = new Flamme(x + i, y, grille, Flamme.HORIZONTALE);
					}
				}
			}
		}
	}

	public static int getAnim() {
		return imageAnim;
	}

	/**
	 * Surcharge de la methode toString pour affichage temporel avant Java2D
	 * 
	 * @return
	 */
	@Override
	public String toString() {
		return "{}";
	}

	@Override
	public boolean equals(Object obj) {
		boolean vrai = false;

		if (obj != null)
			if (getClass().equals(obj.getClass())) {

				final Bombe bo = (Bombe) obj;
				if (this.getX() == bo.getX())
					if (this.getY() == bo.getY())
						if (this.getOwner() == bo.getOwner())
							vrai = true;
			}
		return vrai;
	}

	public static int getRate() {
		return rate;
	}

	public static void setRate(int rate) {
		Bombe.rate = rate;
	}

}
